package engine.util.draw;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;

public class Draw2D {
	
	private static FloatBuffer buffer = BufferUtils.createFloatBuffer(4 * 3 * 2);
	
	//ids for vbo and vao
	private static int vboID;
	private static int vaoID;
	
	private Draw2D() {}
	
	public static void init() {
		vboID = glGenBuffers();
		vaoID = glGenVertexArrays();
	}
	
	public static void destroy() {
		glDeleteBuffers(vboID);
		glDeleteVertexArrays(vaoID);
	}
	
	public static void drawImage(int texture, int x, int y, int width, int height) {
		glBindTexture(GL_TEXTURE_2D, texture);
		
		drawImage(x, y, width, height, 0, 0, 1, 1);
		
		glBindTexture(GL_TEXTURE_2D, 0);
	}
	
	public static void drawImage(int texture, int x, int y, int width, int height, float depth) {
		glBindTexture(GL_TEXTURE_2D, texture);
		
		drawImage(x, y, width, height, 0, 0, 1, 1, depth);
		
		glBindTexture(GL_TEXTURE_2D, 0);
	}
	
	public static void drawImage(float x, float y, float width, float height, float texX, float texY, float texWidth, float texHeight) {
		buffer.rewind();
		//vertices
		buffer.put(x); 			buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y + height);	buffer.put(0);
		buffer.put(x); 			buffer.put(y + height);	buffer.put(0);
		//texcoords
		buffer.put(texX);				buffer.put(texY + texHeight);
		buffer.put(texX + texWidth);	buffer.put(texY + texHeight);
		buffer.put(texX + texWidth);	buffer.put(texY);
		buffer.put(texX);				buffer.put(texY);
		buffer.rewind();
		
		glBindVertexArray(vaoID);
		
		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW);
		
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
		
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 48);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glBindVertexArray(0);
		
		draw(GL_TRIANGLE_FAN, 4);	
	}
	
	public static void drawImage(int x, int y, int width, int height, float texX, float texY, float texWidth, float texHeight, float depth) {		
		buffer.rewind();
		//vertices
		buffer.put(x); 			buffer.put(y);			buffer.put(depth);
		buffer.put(x + width); 	buffer.put(y);			buffer.put(depth);
		buffer.put(x + width); 	buffer.put(y + height);	buffer.put(depth);
		buffer.put(x); 			buffer.put(y + height);	buffer.put(depth);
		//texcoords
		buffer.put(texX);				buffer.put(texY + texHeight);
		buffer.put(texX + texWidth);	buffer.put(texY + texHeight);
		buffer.put(texX + texWidth);	buffer.put(texY);
		buffer.put(texX);				buffer.put(texY);
		buffer.rewind();
		
		glBindVertexArray(vaoID);
		
		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW);
		
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
		
		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 48);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glBindVertexArray(0);
		
		draw(GL_TRIANGLE_FAN, 4);
	}
	
	public static void drawRect(float x, float y, float width, float height) {
		buffer.rewind();
		buffer.put(x); 			buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y + height);	buffer.put(0);
		buffer.put(x); 			buffer.put(y + height);	buffer.put(0);
		buffer.rewind();
		
		glBindVertexArray(vaoID);
		
		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW);
		
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glBindVertexArray(0);
		
		draw(GL_LINE_LOOP, 4);
	}
	
	public static void fillRect(float x, float y, float width, float height) {
		buffer.rewind();
		buffer.put(x); 			buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y);			buffer.put(0);
		buffer.put(x + width); 	buffer.put(y + height);	buffer.put(0);
		buffer.put(x); 			buffer.put(y + height);	buffer.put(0);
		buffer.rewind();
		
		glBindVertexArray(vaoID);
		
		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW);
		
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glBindVertexArray(0);
		
		draw(GL_TRIANGLE_FAN, 4);
	}
	
	public static void drawLine(float startX, float startY, float endX, float endY) {
		buffer.rewind();
		buffer.put(startX); 	buffer.put(startY);		buffer.put(0);
		buffer.put(endX); 		buffer.put(endY);		buffer.put(0);
		buffer.rewind();
		
		glBindVertexArray(vaoID);
		
		glBindBuffer(GL_ARRAY_BUFFER, vboID);
		glBufferData(GL_ARRAY_BUFFER, buffer, GL_DYNAMIC_DRAW);
		
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		glBindVertexArray(0);
		
		draw(GL_LINES, 2);
	}
	
	private static void draw(int type, int length) {
		
		glBindVertexArray(vaoID);
		glDrawArrays(type, 0, length);
		
		glBindVertexArray(0);
		
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
	}
}
